package com.study.manage.service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.study.manage.dal.BlogRepository;
import com.study.manage.dal.BlogStatDayRepository;
import com.study.manage.dal.EvaluateApplyRepository;
import com.study.manage.dal.EvaluateApplyWorkRepository;
import com.study.manage.dal.EvaluateRepository;
import com.study.manage.dal.OrdersRepository;
import com.study.manage.domain.Evaluate;
import com.study.manage.domain.enumm.BlogStatDayType;
import com.study.manage.domain.enumm.EAState;
import com.study.manage.domain.enumm.EvaluateVerify;
import com.study.manage.domain.enumm.PayState;
import com.study.manage.domain.enumm.ReleaseState;
import com.study.manage.utils.DateTimeUtil;


@Component("evaluateService")
public class EvaluateService {

    private static final Logger LOGGER = LoggerFactory.getLogger(EvaluateService.class);

    @Autowired
    private EvaluateApplyRepository evaluateApplyRepository;
    @Autowired
    private EvaluateRepository evaluateRepository;
    @Autowired
    private BlogRepository blogRepository;
    @Autowired
    private OrdersRepository ordersRepository;
    @Autowired
    private BlogStatDayRepository blogStatDayRepository;

    public Map<String, Object> statCount(Long userId, Long evaluateId, ReleaseState state) {
        Date date = new Date();
        Map<String, Object> map = new HashMap<>();
        List<Long> evaluateIds = new ArrayList<>();
        if (evaluateId != null) {
            evaluateIds.add(evaluateId);
        } else {
            evaluateIds = evaluateRepository.findIdByUserIdAndState(userId, state);
        }
        if (evaluateIds.isEmpty()) {
            return map;
        }
        map.put("applyCount", evaluateApplyRepository.countByEvaluateIdInAndVerifyAndState(
                evaluateIds, EvaluateVerify.Pass, EAState.LIVE));
        map.put("dayApplyCount",
                evaluateApplyRepository.countByEvaluateIdInAndVerifyAndStateAndDate(evaluateIds,
                        EvaluateVerify.Pass, EAState.LIVE, date));


        map.put("blogCount", blogRepository.countByTypeAndEvaluateIdAndDate(evaluateIds, null));
        map.put("dayBlogCount", blogRepository.countByTypeAndEvaluateIdAndDate(evaluateIds, date));

        map.put("moneyCount", ordersRepository
                .sumTotalByPayStateAndEvaluateIdInAndDate(PayState.YZF, evaluateIds, null));
        map.put("dayMoneyCount", ordersRepository
                .sumTotalByPayStateAndEvaluateIdInAndDate(PayState.YZF, evaluateIds, date));

        map.put("lookCount", blogStatDayRepository.sumCountByEvaluateIdInAndTypeAndDate(evaluateIds,
                BlogStatDayType.Look, null));
        map.put("dayLookCount", blogStatDayRepository
                .sumCountByEvaluateIdInAndTypeAndDate(evaluateIds, BlogStatDayType.Look, date));

        map.put("openCount", blogStatDayRepository.sumCountByEvaluateIdInAndTypeAndDate(evaluateIds,
                BlogStatDayType.Open, null));
        map.put("dayOpenCount", blogStatDayRepository
                .sumCountByEvaluateIdInAndTypeAndDate(evaluateIds, BlogStatDayType.Open, date));


        List<BlogStatDayType> bsts = new ArrayList<>();
        bsts.add(BlogStatDayType.Like);
        bsts.add(BlogStatDayType.Grade);
        bsts.add(BlogStatDayType.PL);
        bsts.add(BlogStatDayType.TL);
        bsts.add(BlogStatDayType.Vote);
        map.put("hdCount", blogStatDayRepository.sumCountByEvaluateIdInAndTypeInAndDate(evaluateIds,
                bsts, null));
        map.put("dayHDCount", blogStatDayRepository
                .sumCountByEvaluateIdInAndTypeInAndDate(evaluateIds, bsts, date));
        return map;
    }

    @Autowired
    private EvaluateApplyWorkRepository evaluateApplyWorkRepository;

    public List<Map<String, Object>> listStatCount(Long evaluateId, List<Long> referenceId,
            String type, Date beginAt, Date endAt) {
        List<Object[]> objs = new ArrayList<>();
        List<Long> evaluateIds = new ArrayList<>(Arrays.asList(evaluateId));
        Evaluate e = evaluateRepository.findOne(evaluateId);
        if (beginAt == null || endAt == null) {
            beginAt = e.beginAt;
            endAt = e.endAt;
        }
        if ("BM".equals(type)) {
            // 是否是推荐人数据
            if (referenceId != null && !referenceId.isEmpty()) {
                objs = evaluateApplyRepository.countByEvaluateIdInAndReferenceIdInGroupByDays(
                        referenceId, beginAt, endAt, evaluateIds);
            } else {
                objs = evaluateApplyRepository.countByEvaluateIdInGroupByDays(beginAt, endAt,
                        evaluateIds);
            }
        } else if ("ZP".equals(type)) {
            objs = evaluateApplyWorkRepository.countByEvaluateIdInGroupByDays(beginAt, endAt,
                    evaluateIds);
        } else if ("SF".equals(type)) {
            objs = ordersRepository.countByEvaluateIdInGroupByDays(beginAt, endAt, evaluateIds);
        } else if ("LL".equals(type)) {
            objs = blogStatDayRepository.countShowByEvaluateIdInGroupByDay(beginAt, endAt,
                    evaluateIds);
        } else if ("DK".equals(type)) {
            objs = blogStatDayRepository.countOpendByEvaluateIdInGroupByDay(beginAt, endAt,
                    evaluateIds);
        } else if ("HD".equals(type)) {
            objs = blogStatDayRepository.countHudongByEvaluateIdInGroupByDays(beginAt, endAt,
                    evaluateIds);
        }
        List<Map<String, Object>> list = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(beginAt);
        while (cal.getTime().getTime() <= endAt.getTime()) {
            String nowDate = DateTimeUtil.format(cal.getTime(), DateTimeUtil.DATE_PATTERN_SHORT);
            Map<String, Object> map = new HashMap<>();
            for (Object[] os : objs) {
                Timestamp time = (Timestamp) os[0];
                String nTime = DateTimeUtil.format(new Date(time.getTime()),
                        DateTimeUtil.DATE_PATTERN_SHORT);
                if (nTime.equals(nowDate)) {
                    map.put(os[2].toString(), os[1]);
                }
            }
            map.put("date", nowDate + "(" + DateTimeUtil.getDaysInWeek(cal.getTime()) + ")");
            list.add(map);
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }
        Collections.sort(list, new Comparator<Map<String, Object>>() {
            public int compare(Map<String, Object> arg0, Map<String, Object> arg1) {
                return ((String) arg1.get("date")).compareTo(((String) arg0.get("date")));
            }
        });
        return list;
    }
}
